﻿using AutoMapper;
using Enter.Dashboard.Api;
using Enter.Dashboard.Api.Entities;
using Enter.Enums;
using Enter.Utils.CacheExt;
using Enter.Utils.CryptoExt;
using Enter.Utils.EnumExt;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Enter.Dashboard.Api.Controllers
{
    public class BaseController : ControllerBase
    {
        protected readonly IFreeSql _fsql;
        protected readonly IMapper _mapper;
        protected readonly IDistributedCache _cache;
        protected readonly ILogger _logger;

        public BaseController(ILogger<BaseController> logger, IDistributedCache cache, IFreeSql fsql, IMapper mapper)
        {
            _logger = logger;
            _cache = cache;
            _fsql = fsql;
            _mapper = mapper;
        }

        protected string TokenStr()
        {
            return HttpContext.GetToken();
        }

        protected Token Token()
        {
            var tokenStr = TokenStr();
            if (string.IsNullOrWhiteSpace(tokenStr))
            {
                return null;
            }
            return TokenExtend.Pase(tokenStr);
        }

        protected string UpdateSession(long userId = 0, Employ user = null)
        {
            var tokenStr = TokenStr();
            Token token = null;
            if (string.IsNullOrWhiteSpace(tokenStr))
            {
                if (userId <= 0)
                {
                    if (user != null)
                    {
                        userId = user.Id;
                    }
                    else
                    {
                        throw new Exception("参数错误.");
                    }
                }
                token = TokenExtend.NewToken(userId);
                tokenStr = token.ToString();
            }
            else
            {
                token = TokenExtend.Pase(tokenStr);
            }

            var session = _cache.Get<Employ>(token.Id);
            if (session != default)
            {
                if (userId == 0)
                    userId = session.Id;
                if (userId == session.Id)
                {
                    user = _fsql.Select<Employ>().Include(t => t.Role).Where(t => t.Id == session.Id).First();
                }
            }
            if (user != null)
            {
                _cache.Set(token.Id, user);
            }
            return tokenStr;
        }

        public static void UpdateEnumDictionary(IFreeSql _fsql)
        {
            var enum_group = _fsql.Select<EnumDictionary>().ToList().GroupBy(t => t.DicType);
            foreach (var enumOne in enum_group)
            {
                var key = enumOne.Key;
                var items = new List<EnumSelectListItem>();
                foreach (var g in enumOne.OrderBy(t => t.Sort))
                {
                    items.Add(new EnumSelectListItem { Value = g.Value, Text = g.Text });
                }
                EnumExtend.EnumMap.AddOrUpdate(key, items, (oldkey, oldvalue) => items);
            }
        }

        public static void UpdateUserList(IFreeSql _fsql)
        {
            var users = _fsql.Select<Employ>().Where(t => t.IsDeleted == false).ToList()
            .Select(t => new EnumSelectListItem { Value = t.Id.ToString(), Text = t.TrueName }).ToList();
            EnumExtend.EnumMap.AddOrUpdate(nameof(EnumArchive.EnumEmploy), users, (oldkey, oldvalue) => users);
        }

        public static void UpdateDynamicTableList(IFreeSql _fsql)
        {
            var tables = _fsql.Select<DynamicTable>().ToList()
            .Select(t => new EnumSelectListItem { Value = t.Id.ToString(), Text = t.Name }).ToList();
            EnumExtend.EnumMap.AddOrUpdate(nameof(EnumArchive.EnumDynamicTable), tables, (oldkey, oldvalue) => tables);
        }

        public static void Init(IFreeSql _fsql, IConfiguration configuration)
        {
            // 初始化数据库配置;
            var settings = _fsql.Select<Setting>().ToList();
            foreach (var setting in settings)
            {
                configuration[setting.Key] = setting.Value;
            }
            // 初始化用户;
            UpdateUserList(_fsql);
            // 初始化枚举;
            UpdateEnumDictionary(_fsql);
            // 初始化所属机构;
            UpdateDynamicTableList(_fsql);
        }

        protected Employ Session()
        {
            var tokenStr = TokenStr();
            if (string.IsNullOrWhiteSpace(tokenStr))
            {
                return null;
            }
            var token = TokenExtend.Pase(tokenStr);
            return _cache.Get<Employ>(token.Id);
        }
    }
}
